package com.autumn.sms.aliyun;

import java.util.List;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.autumn.sms.AbstractSmsChannel;
import com.autumn.sms.SmsChannelConfigure;
import com.autumn.sms.SmsChannelException;
import com.autumn.sms.SmsMessage;
import com.autumn.sms.aliyun.model.SendSmsRequest;
import com.autumn.sms.aliyun.model.SendSmsResponse;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.StringUtils;
import com.autumn.util.json.JsonUtils;

/**
 * 阿里云短信通道
 * 
 * @author 杨昌国 2018-12-07 10:34:36
 */
public class AliyunSmsChannel extends AbstractSmsChannel {

	/**
	 * 
	 * 通道Id
	 */
	public static final String CHANNEL_ID = "aliyunSMS";

	/**
	 * 
	 * 通道名称
	 */
	public static final String CHANNEL_NAME = "阿里云短信";

	// 产品名称:云通信短信API产品,开发者无需替换
	private static final String product = "Dysmsapi";
	// 产品域名,开发者无需替换
	private static final String domain = "dysmsapi.aliyuncs.com";

	private static final String ACCESS_KEY_ID = "accessKeyId";
	private static final String ACCESS_KEY_SECRET = "accessKeySecret";

	private String accessKeyId;
	private String accessKeySecret;
	private String defaultSignName;

	/**
	 * 
	 */
	static {
		DefaultProfile.addEndpoint("cn-hangzhou", product, domain);
	}

	/**
	 * 获取访问键Id
	 * 
	 * @return
	 */
	public String getAccessKeyId() {
		return accessKeyId;
	}

	/**
	 * 设置访问键Id
	 * 
	 * @param accessKey
	 */
	public void setAccessKeyId(String accessKeyId) {
		this.accessKeyId = accessKeyId;
	}

	/**
	 * 获取访问键密钥
	 * 
	 * @return
	 */
	public String getAccessKeySecret() {
		return accessKeySecret;
	}

	/**
	 * 获取默认签名
	 * 
	 * @return
	 */
	public String getDefaultSignName() {
		return defaultSignName;
	}

	/**
	 * 设置默认签名
	 * 
	 * @param defaultSignName
	 */
	public void setDefaultSignName(String defaultSignName) {
		this.defaultSignName = defaultSignName;
	}

	/**
	 * 设置访问键密钥
	 * 
	 * @param accessKeySecret
	 *            访问键密钥
	 */
	public void setAccessKeySecret(String accessKeySecret) {
		this.accessKeySecret = accessKeySecret;
	}

	@Override
	public String getChannelCode() {
		return CHANNEL_ID;
	}

	@Override
	public String getChannelName() {
		return CHANNEL_NAME;
	}

	/**
	 * 分页大小
	 */
	private static final int MAX_SEND_PHONE_NUMBERS = 1000;

	@Override
	protected void InternalSend(SmsMessage message, SmsChannelConfigure channelConfigure) throws Exception {
		String signName = message.getSignName();
		if (StringUtils.isNullOrBlank(signName)) {
			signName = this.getDefaultSignName();
		}
		if (StringUtils.isNullOrBlank(signName)) {
			ExceptionUtils.throwValidationException("signName 为空。");
		}
		Object accessKeyId = channelConfigure.get(ACCESS_KEY_ID, this.getAccessKeyId());
		if (accessKeyId == null || StringUtils.isNullOrBlank(accessKeyId.toString())) {
			ExceptionUtils.throwValidationException("无法从配置中获取 " + ACCESS_KEY_ID + " 的值或值为空");
		}
		Object accessKeySecret = channelConfigure.get(ACCESS_KEY_SECRET, this.getAccessKeySecret());
		if (accessKeySecret == null || StringUtils.isNullOrBlank(accessKeySecret.toString())) {
			ExceptionUtils.throwValidationException("无法从配置中获取 " + ACCESS_KEY_SECRET + " 的值或值为空");
		}
		IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId.toString().trim(),
				accessKeySecret.toString().trim());
		IAcsClient acsClient = new DefaultAcsClient(profile);
		List<String> pages = this.phoneNumberPages(message.getPhoneNumbers(), message.getNationCode(),
				MAX_SEND_PHONE_NUMBERS);
		for (String page : pages) {
			SendSmsRequest request = new SendSmsRequest();
			request.setPhoneNumbers(page);
			request.setSignName(signName);
			request.setTemplateCode(message.getTemplateCode());
			request.setTemplateParam(JsonUtils.toJSONString(message.getParams()));
			SendSmsResponse response;
			try {
				response = acsClient.getAcsResponse(request);
				if (!"OK".equalsIgnoreCase(response.getCode())) {
					throw new SmsChannelException(response.getMessage());
				}
			} catch (ServerException e) {
				throw new SmsChannelException(e.getMessage(), e);
			} catch (ClientException e) {
				throw new SmsChannelException(e.getMessage(), e);
			}
		}
	}
}
